/*
	
	
*******************
* Check G :
*  
*   - find tradelit,  will, trade list : 
*      ==  exist : w no check G
* 
*  - if can find mytem in tradelist 
*  		:skip buy 
* 
*   - if find my tem in  will /trade list
*   	: skip trade  
* 
*********
*   min G : up  relate to ll 
* s num : ralted lv.. 

**  interval : longer relate to ll . 
* **  i wrap :  wait longer...
*
* check G :  bar update every time..
 
*/	
"use strict";

// step 1 :  seq Q : bld & sttudy  
//		:  trade  on  

// step 2 : wait till sold trade item

// step 3 : when g > 30 0000  :   bld, strdy, train, check res < 20 000 : trade again 	
function CSP30Action() {
	this.objName = "CSP30Action: ";
	
	this.step = 1; 
	this.nth = -1;
	this.actionSeq = new CActionSeq();

	debug.log(this, ' Created Init Qst ');
	
	var self = this;
	this.force_stop = false;
	em.cbs.forcestop.add ( function() {self.force_stop = true; 
							debug.log(self,'Set ForceStop ::' , self.force_stop);  });
	
	if ( em.place == 'office') {
		this.cit_timeout = 125000;
		debug.log( this, ' OFFICE timeout ', this.cit_timeout) ;
	} else {
		this.cit_timeout = 60000;
	}
	
	// set trade tem & price by server
	var tem = CDB.SP30.getTemInfo();
		this.tem_id = tem.sid; // ally token 
		this.tem_price = tem.price;
		this.tem_step3_price = tem.step3_price;
		this.tem_type = tem.type;  
	
/*
	if ( CDB.getCurUserInfo().serverinfo.name == 'Ania') {
		this.tem_id = 113; // ally token 
		this.tem_price = 280089;
		this.tem_step3_price = 1500089;
		this.tem_type = 3; 
	} else {
		// Hipo 
		this.tem_id = 73; // wp 
		this.tem_price = 160089;
		this.tem_step3_price = 1400089;
		// this.tem_step3_price = 800089;
		this.tem_type = 1; 
	}*/

	
	debug.log( this, ' ~~~~~~IMPORTANT!! ~~~~~~~~ SET Trade Id ; ', this.tem_id, ' Price: ', this.tem_price, ' Type:', this.tem_type);
	
	/*
		 step 1 tbl 
	*/
	// Important !!! : deep copy !! : pop from array 
	this.taskSeq =  CSP30Action.taskSeqTbl.slice();
	/*
		 step 3 table 
	*/
	// Important !!! : deep copy !! : pop from array 
	this.step3_bld_tbl = CSP30Action.STEP3_BLD_TBL.slice();
		
	// Important !!! : deep copy !! : pop from array 
	this.step3_study_tbl = CSP30Action.STEP3_STUDY_TBL.slice();
	
	this.initialize();
};		


// define class var 
CSP30Action.taskSeqTbl =  [

	// sub 0  :   : til trade up 
	[
		// Q - acc house 
		{ name: 'checkQst_First', fn: 'conductQst',  param: { 'action': 'task_up', 'id': 1 } ,retry: 0 },
		// bld Hou
		{ name: 'buildHouse', fn: 'conductBld', param: { bld: CDB.BUILD.HOU, lv: 0} , retry: 0 },
		// gift today : ignore...  
		// GET /game/goods_api.php?jsonpcallback=jsonp1326014287244&_=1326014414673&key=0314fac3e037989c062370584d3dc99b&action=gift&id=168&_l=en&_p=EW-DROID HTTP/1.1

		//  * buy gold chest  & use 
		{ name: 'buy_Gold_Chest', fn: 'buyGemItem', param: { cat: 5 , id: 131} ,retry: 0 }, // 49 "id":75644,"sid":131, : g chest 
		{ name: 'useItem_Chest__!!!', fn: 'useItem', param: { type: 3 , sid: 131,  id: 75644 , num: 1} ,retry: 0 }, // 
		{ name: 'useItem_ref___!!!', fn: 'useItem', param: { type: 3 , sid: 169, id: 75606 , num: 1} ,retry: 0 }, // "id":75606,"sid":169, : ref  

		// * sell item.  recrute *3 
		// { name: 'saleItem_ref_118_3', fn: saleItem, param: { type: 3 , sid: 118, id: 0 , num: 3} ,retry: 0 }, //  ref
		 { name: 'saleItem_ref_RP_3', fn: 'saleItem', param: { type: 3 , sid: 161, id: 0, num: 3} ,retry: 0 }, //  ref  &id=75618  , sid  115 

		// wait complet  cd type 1 
		{ name: 'checkCd_WaitHOU', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.HOU.type} , retry: 0 },

		// build Farm next Qst
		{ name: 'buildFAR', fn: 'conductBld', param: { bld: CDB.BUILD.FAR, lv: 0} ,retry: 0 },

		//		* Q - done : hou
		{ name: 'checkQst_DoneHou', fn: 'conductQst', param: { 'action': 'task_end', 'id': 1} ,retry: 0 },

		// expand bld slot  with bless 	
		// gift jan
		// ymywpwx   : tapsg 
		{ name: 'getGift', fn: 'getGift', param: 'ymywpwx', retry: 0 },// 1  , 5v6hczj : x-ma
		// { name: 'getGift', fn: getGift, param: '3hp6xfs', fault_action: 'skip', retry: 0 },//
		// { name: 'getGift', fn: getGift, param: 'Xpp0is3',retry: 0 },	// 1
		
		{ name: 'useBless7_1', fn: 'useItem', param: { sid: 166, id: 75614 , num: 1} ,retry: 0 },	//  11 "  id":75614,"sid":167, 30days 
		
		{ name: 'buildWoo_sawmill', fn: 'conductBld', param: { bld: CDB.BUILD.MIL /* mill */, lv: 0} ,retry: 0 },

		{ name: 'checkQst_UP_BldFar', fn: 'conductQst', param: { 'action': 'task_up', 'id': 2 } ,retry: 0 },
		
		
		// buy All Tk 
		{ name: 'buy_TEM', fn: 'buyTradeItem', param: { type: 0 , id:  0} ,retry: 0 }, //   :: use db  tem id. 
		
		// trade.. up. .. 
		{ name: 'trade_regi_TEM', fn: 'tradeReg', param: { sid: 0 , id: 0, num: 1, price: 0  } ,retry: 0 }, //  11
	
		
		// check Q 
		// { name: 'checkQst_LIST', fn: conductQst, param: { 'action': 'task_list', 'id': NaN } ,retry: 0 },
		{ name: 'checkCd_WaitBldFar', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.FAR.type} , retry: 0 },
		 
		{ name: 'checkQst_END_BldFar', fn: 'conductQst', param: { 'action': 'task_end', 'id': 2 } ,retry: 0 },
		{ name: 'checkQst_UP_BldIro', fn: 'conductQst', param: { 'action': 'task_up', 'id': 14 } ,retry: 0 },	// I 
		// build w, gm 		
		{ name: 'build_IronMine', fn: 'conductBld', param: { bld: {name: 'Wood', pos: 13, type: 2} /* w */, lv: 0} ,retry: 0 },
		{ name: 'build_GolMin', fn: 'conductBld', param: { bld: {name: 'GldMine', pos: 14, type: 3} /* g m */, lv: 0} ,retry: 0 },	// take longer time
	
	
		// check trade success 
		{ name:'ck_TRade_List', fn: 'checkTrade', param: { sid: 0  } ,retry: 0 },	//  
		

			// wait complet  cd type 1 
		{ name: 'checkCd_WaitMil', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: 1} , retry: 0 },

		
		{ name: 'checkCd_wait_GolMin', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: 3 } , retry: 0 },
	

		// Check Q 
		// { name: 'checkQst_LIST', fn: conductQst, param: { 'action': 'task_list', 'id': NaN } ,retry: 0 }, // 
		{ name: 'checkQst_END_GolMin', fn: 'conductQst', param: { 'action': 'task_end', 'id': 14 } ,retry: 0 },	//  gm
		
		{ name: 'checkQst_UP_Woo', fn: 'conductQst', param: { 'action': 'task_up', 'id': 15 } ,retry: 0 },	//  w 
		{ name: 'checkQst_END_Woo', fn: 'conductQst', param: { 'action': 'task_end', 'id': 15 } ,retry: 0 },	//  
		{ name: 'checkQst_UP_I?', fn: 'conductQst', param: { 'action': 'task_up', 'id': 16 } ,retry: 0 },	//  
		{ name: 'checkQst_END_I?', fn: 'conductQst', param: { 'action': 'task_end', 'id': 16 } ,retry: 0 },	//  

		// build facil
		{ name: 'checkQst_UP_Fac', fn: 'conductQst', param: { 'action': 'task_up', 'id': 3 } ,retry: 0 },	//  30  
		{ name: 'build_Facility', fn: 'conductBld', param: { bld: CDB.BUILD.FAC, lv: 0} ,retry: 0 }, // wait 1: 30 
		
		// get bless & use bless 
		{ name: 'useBless7777', fn: 'useItem', param: {"id":75635,"sid":166 , num : 1} ,retry: 0 }, //  7 days "id":75635,"sid":166,
		//get use info 
		{ name: 'getUserInfo', fn: 'getUserInfo', param: { } ,retry: 0 }, // why?? 

		
	],
	// =======================================================		
	// =======================================================
	// sub 1  :  wait FAC :  over 1 min  
	[
			// sbu2 : first check trade state .
		{ name: 'Check_TRade_List', fn: 'checkTrade', param: { sid: 0 } ,retry: 0 },	
		
			// 빨리 gold check 한다. 
			// check g  >  xxxxx 
		{ name: 'Wait_Sold:chkG:', fn: 'CheckRes', param: { res: {g: 50000} } , 'fault_action': 'abort', retry: 0 }, //barr

		// bld uni 
		{ name: 'build_UNI', fn: 'conductBld', param: { bld: CDB.BUILD.UNI , lv: 0} ,retry: 0 }, // 17 min 
		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastBld1_Uni1', fn: 'fastActionTem', param: { 'type': 1  , 'sid': 115, 'cdtype': 1, 'target': CDB.BUILD.UNI.type} ,retry: 0 }, // 1: build 


		{ name: 'checkCd_Wait_FAC', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.FAC.type } , retry: 0 },
		{ name: 'checkQst_END_BldFAC', fn: 'conductQst', param: { 'action': 'task_end', 'id': 3 } ,retry: 0 },	// facil   

			// build barr		
		{ name: 'build_Barr', fn: 'conductBld', param: { bld: CDB.BUILD.BAR, lv: 0} ,retry: 0 }, //barr 1:50

		{ name: 'checkQst_UP_BAR', fn: 'conductQst', param: { 'action': 'task_up', 'id': 4 } ,retry: 0 },	// bar   
			
		// study .. & desc secs. 
		// { name: 'Study_Forge', fn: 'conductStudy', param: { 'tech': CDB.STUDY.FORGING.type , lv: 0} ,retry: 0 }, // //  wait 11:00

		{ name: 'checkCd_Wait_BAR', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.BAR.type } , retry: 0 },
		{ name: 'checkQst_END_BAR', fn: 'conductQst', param: { 'action': 'task_end', 'id': 4 } ,retry: 0 },	// bar   
			
		{ name: 'checkQst_UP_TrainSol', fn: 'conductQst', param: { 'action': 'task_up', 'id': 17 } ,retry: 0 },	// train sol   

		// less Mo : 21 Min  
		{ name: 'build_UNI2', fn: 'conductBld', param: { bld: CDB.BUILD.UNI , lv: 1} ,retry: 0 }, //
		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastBld2_Uni2', fn: 'fastActionTem', param: { 'type': 1  , 'sid': 115, 'cdtype': 1, 'target': CDB.BUILD.UNI.type} ,retry: 0 }, // 2 : study, 

		// check status cstl .. 
		{ name: 'Update_CstlInfo', fn: 'getCurCstlInfo', param: { } ,retry: 0 }, //  
	],
	
	// =======================================================
	// sub 2  :  less m .. wait .. trade..   
	[
	
		// sbu2 : first check trade state .
		{ name: 'Check_TRade_List', fn: 'checkTrade', param: { sid: 0 } ,retry: 0 },	
		
		// check g  >  xxxxx 
		{ name: 'Wait_Sold:chkG:', fn: 'CheckRes', param: { res: {g: 50000} } , 'fault_action': 'abort', retry: 0 }, //barr

		// wait pre uni bld end..
		{ name: 'checkCd_Wait_UNI2', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.UNI.type } ,'fault_action': 'abort' ,retry: 0 },		  

		{ name: 'train_Infan', fn: 'trainSol', param: { trs: {type:  1, num: 10 } } ,retry: 0 },	// train sol

		//	 UNI 3
		{ name: 'build_UNI3', fn: 'conductBld', param: { bld: CDB.BUILD.UNI , lv: 2} ,retry: 0 }, //

		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastBld3_Uni3', fn: 'fastActionTem', param: { 'type': 1  , 'sid': 115, 'cdtype': 1, 'target': CDB.BUILD.UNI.type} ,retry: 0 }, // 2 : study, 

	
		// study .. & desc secs. 
		// { name: 'Study_March', fn: 'conductStudy', param: { 'tech': CDB.STUDY.MARCHING.type , lv: 0} ,retry: 0 }, // 45  //  wait 11:00

		// type , param.sid, param.cdtype, param.target,  
		// { name: 'Use_FastRes1_Mar', fn: 'fastActionTem', param: { 'type': 2  , 'sid': 118, 'cdtype': 2, 'target': CDB.STUDY.MARCHING.type} ,retry: 0 }, // 2 : study, 

			// are
		{ name: 'build_Area', fn: 'conductBld', param: { bld: CDB.BUILD.ARE, lv: 0} ,retry: 0 }, //  longer tha barr


		// check status cstl .. 
		{ name: 'Update_CstlInfo', fn: 'getCurCstlInfo', param: { } ,retry: 0 }, //  

// =======================================================
	

		{ name: 'Study_Sco', fn: 'conductStudy', param: { 'tech': CDB.STUDY.SCOUTING.type , lv: 0} ,retry: 0 }, // 45  //  wait 11:00
		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastRes1_Sco', fn: 'fastActionTem', param: { 'type': 2  , 'sid': 118, 'cdtype': 2, 'target': CDB.STUDY.SCOUTING.type} ,retry: 0 }, // 2 : study, 
],

	// =======================================================
	// sub 3  :  wait train ifan,  bld area,.. 
[
		// wait  sol train    
		{ name: 'checkCd_Wait_Train_Inf', fn: 'checkCd', param: { cdtype: CDB.CDS.TRAIN, target: 1 /*sol type*/ } , retry: 0 },
		{ name: 'checkQst_END_TrainSol', fn: 'conductQst', param: { 'action': 'task_end', 'id': 17 } ,retry: 0 },	// train sol   

		// hire h 
		{ name: 'checkCd_Wait_AREN', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },
		{ name: 'hire_H_1st', fn: 'hireH', param: {  } ,retry: 0 },	// 

		{ name: 'build_Area_2', fn: 'conductBld', param: { bld: CDB.BUILD.ARE , lv: 1} ,retry: 0 }, //barr 1:20
		{ name: 'build_Barr_2', fn: 'conductBld', param: { bld: CDB.BUILD.BAR , lv: 1} ,retry: 0 }, //barr 1:20


			// done hire H 
		{ name: 'checkQst_UP_AREN', fn: 'conductQst', param: { 'action': 'task_up', 'id': 5 } ,retry: 0 },	//  ARENA 
		{ name: 'checkQst_END_AREN', fn: 'conductQst', param: { 'action': 'task_end', 'id': 5 } ,retry: 0 },	// ARENA
		
		//
		{ name: 'checkQst_UP_Hire_H', fn: 'conductQst', param: { 'action': 'task_up', 'id': 18 } ,retry: 0 },	// hire H    
		{ name: 'checkQst_END_Hire_H', fn: 'conductQst', param: { 'action': 'task_end', 'id': 18 } ,retry: 0 },	// hire H     

		// Q bld Uni
		{ name: 'checkQst_UP_Bld_Uni', fn: 'conductQst', param: { 'action': 'task_up', 'id': 6 } ,retry: 0 },	// bld uni   
		// { name: 'checkCd_Wait_Bld_Uni', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.UNI.type } , retry: 0 }, 
		{ name: 'checkQst_END_Bld_Uni', fn: 'conductQst', param: { 'action': 'task_end', 'id': 6 } ,retry: 0 },	// 

		//  study forge
		{ name: 'checkQst_UP_Strudy_Forge', fn: 'conductQst', param: { 'action': 'task_up', 'id': 19 } ,retry: 0 },	// study forge  
	
		// 
		{ name: 'Study_Logi', fn: 'conductStudy', param: { 'tech': CDB.STUDY.LOGISTICS.type , lv: 0} ,retry: 0 }, // 45  //  wait 11:00
		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastRes2_Logi', fn: 'fastActionTem', param: { 'type': 2  , 'sid': 118, 'cdtype': 2, 'target': CDB.STUDY.LOGISTICS.type} ,retry: 0 }, // 2 : study,
		
		// wait pre uni bld end..
		{ name: 'checkCd_Wait_UNI3', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.UNI.type } , retry: 0 },		  

		//	 UNI 4
		{ name: 'build_UNI4', fn: 'conductBld', param: { bld: CDB.BUILD.UNI , lv: 3} ,retry: 0 }, //barr
		 
		{ name: 'Check_TRade_List', fn: 'checkTrade', param: { sid: 0 } ,retry: 0 },	//   
	],

	// subs 4 .. wait uni 
	[
		// wait pre uni bld end..
		{ name: 'checkCd_Wait_UNI4', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.UNI.type } , retry: 0 },		  
		//	 UNI 4
		{ name: 'build_UNI5', fn: 'conductBld', param: { bld: CDB.BUILD.UNI , lv: 4} ,retry: 0 }, //barr

		// bld Hou
		{ name: 'buildHouse2', fn: 'conductBld', param: { bld: CDB.BUILD.HOU, lv: 1} , retry: 0 },

		// sty ef 
		{ name: 'Study_EfTr', fn: 'conductStudy', param: { 'tech': CDB.STUDY.EFF_TRAINING.type , lv: 0} ,retry: 0 }, // 45  //  wait 11:00
		// type , param.sid, param.cdtype, param.target,  
		{ name: 'Use_FastRes3_Logi', fn: 'fastActionTem', param: { 'type': 2  , 'sid': 118, 'cdtype': 2, 'target': CDB.STUDY.EFF_TRAINING.type} ,retry: 0 }, // 2 : study,

		// hire h 
		{ name: 'checkCd_Wait_AREN2', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },
		{ name: 'build_Area_3', fn: 'conductBld', param: { bld: CDB.BUILD.ARE , lv: 3} ,retry: 0 }, //barr 1:20	
	],

	// sub s  :   train Inf 
	
	// sub :   confirm bld uni & study forge
	
	// sub : til  ... 
	/*
	[
			// bld house 2 & barr 2  & arena 2 
			{ name: 'build_Hou_2', fn: 'conductBld', param: { bld: CDB.BUILD.HOU , lv: 1} ,retry: 0 }, //barr 1:20
			
			{ name: 'checkCd_Wait_Study_Forge', fn: 'checkCd', param: { cdtype: CDB.CDS.BLD, target: CDB.STUDY.FORGING.type } , retry: 0 }, 
			{ name: 'checkQst_END_Study_Forge', fn: 'conductQst', param: { 'action': 'task_end', 'id': 19} ,retry: 0 },	//  forge done
	
			{ name: 'checkQst_UP_BldWall', fn: 'conductQst', param: { 'action': 'task_up', 'id': 7} ,retry: 0 },	//  wall 
	
		],*/
	
		// { name: 'saleItem_ref_161_3', fn: saleItem, param: { type: 3 , sid: 161, id: 0, num: 3} ,retry: 0 }, //  ref  &id=75620 , // sid 161
		
	
/*
		// WAIT anrea 		
		{ name: 'checkCd_Wait_Aren2', fn: checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },

		// bld aran 3 		
		{ name: 'build_Area_2', fn: conductBld, param: { type: CDB.BUILD.ARE.type , lv: 1} ,retry: 0 }, //barr 1:20
		{ name: 'checkCd_Wait_Aren2', fn: checkCd, param: { cdtype: CDB.CDS.BLD, target: CDB.BUILD.ARE.type } , retry: 0 },
		 */

		// wall acc 
	];
	
CSP30Action.STEP3_BLD_TBL  = [
		[ CDB.BUILD.BAR.type, 1 ],
		[ CDB.BUILD.ARE.type, 1 ],
		
		[ CDB.BUILD.FAC.type, 1 ],
		[ CDB.BUILD.FAC.type, 2 ],
		[ CDB.BUILD.FAC.type, 3 ],
		
		[ CDB.BUILD.UNI.type, 1 ],
		[ CDB.BUILD.UNI.type, 2 ],
		[ CDB.BUILD.UNI.type, 3 ],

		[ CDB.BUILD.HOU.type, 1 ],
		[ CDB.BUILD.HOU.type, 2 ],
		[ CDB.BUILD.HOU.type, 3 ],
		
		[ CDB.BUILD.ARE.type, 2 ],
		[ CDB.BUILD.ARE.type, 3 ],
		
		[ CDB.BUILD.BAR.type, 2 ],
		[ CDB.BUILD.BAR.type, 3 ],
		
		[ CDB.BUILD.FAC.type, 4 ],	
		[ CDB.BUILD.HOU.type, 4 ],
		[ CDB.BUILD.UNI.type, 4 ],
		
		[ CDB.BUILD.BAR.type, 4 ],
		[ CDB.BUILD.FAC.type, 5 ],	
		[ CDB.BUILD.HOU.type, 5 ],

		[ CDB.BUILD.FAC.type, 6 ],	
		[ CDB.BUILD.BAR.type, 5 ],
		[ CDB.BUILD.UNI.type, 5 ],
		
		[ CDB.BUILD.BAR.type, 6 ],
		[ CDB.BUILD.UNI.type, 6 ],
		[ CDB.BUILD.HOU.type, 6 ],
		
		[ CDB.BUILD.FAR.type, 2 ],
		[ CDB.BUILD.FAR.type, 3 ],
		
		[ CDB.BUILD.UNI.type, 7 ],
		[ CDB.BUILD.MIL.type, 2 ],
		[ CDB.BUILD.FAR.type, 5 ],
		[ CDB.BUILD.MIL.type, 3 ],

				
		[ CDB.BUILD.UNI.type, 8 ],
		[ CDB.BUILD.MIL.type, 4 ],
		[ CDB.BUILD.FAR.type, 5 ],

		[ CDB.BUILD.UNI.type, 9 ],
		[ CDB.BUILD.MIL.type, 5 ],
		[ CDB.BUILD.FAR.type, 6 ],

		[ CDB.BUILD.UNI.type, 10 ],
		[ CDB.BUILD.MIL.type, 6 ],
		[ CDB.BUILD.FAR.type, 7 ],

		[ CDB.BUILD.UNI.type, 11 ],
		[ CDB.BUILD.MIL.type, 7 ],
		[ CDB.BUILD.FAR.type, 8 ],

		[ CDB.BUILD.UNI.type, 12 ],
		[ CDB.BUILD.MIL.type, 8 ],
		[ CDB.BUILD.FAR.type, 9 ],

		[ CDB.BUILD.UNI.type, 13 ],
		[ CDB.BUILD.MIL.type, 9 ],
		[ CDB.BUILD.FAR.type, 10 ],

		[ CDB.BUILD.MIL.type, 10 ],
		[ CDB.BUILD.FAR.type, 11 ],

		[ CDB.BUILD.MIL.type, 11 ],
		[ CDB.BUILD.FAR.type, 12 ],
		[ CDB.BUILD.MIL.type, 12 ],
		[ CDB.BUILD.FAR.type, 13 ],
		[ CDB.BUILD.MIL.type, 13 ],
		[ CDB.BUILD.FAR.type, 14 ],
		[ CDB.BUILD.MIL.type, 14 ],
		[ CDB.BUILD.FAR.type, 15 ],
	];	  	

CSP30Action.STEP3_STUDY_TBL = [
		[ CDB.STUDY.FORGING.type, 1 ],
		[ CDB.STUDY.MARCHING.type, 1 ],
		[ CDB.STUDY.SCOUTING.type, 1 ],
		[ CDB.STUDY.LOGISTICS.type, 1 ],
		[ CDB.STUDY.EFF_TRAINING.type, 1 ],
		[ CDB.STUDY.EFF_TRAINING.type, 2 ],
		[ CDB.STUDY.EFF_TRAINING.type, 3 ],
		[ CDB.STUDY.EFF_TRAINING.type, 4 ],
		[ CDB.STUDY.EFF_TRAINING.type, 5 ],
		[ CDB.STUDY.EFF_TRAINING.type, 6 ],
		[ CDB.STUDY.EFF_TRAINING.type, 7 ],
		[ CDB.STUDY.EFF_TRAINING.type, 8 ],
		[ CDB.STUDY.EFF_TRAINING.type, 9 ],
		[ CDB.STUDY.EFF_TRAINING.type, 10 ],
		[ CDB.STUDY.EFF_TRAINING.type, 11 ],
		[ CDB.STUDY.EFF_TRAINING.type, 12 ],
		[ CDB.STUDY.EFF_TRAINING.type, 13 ],
		[ CDB.STUDY.EFF_TRAINING.type, 14 ],
		[ CDB.STUDY.EFF_TRAINING.type, 15 ],
	];	  	
		


	
CSP30Action.prototype = {

	initialize: function() {


		this.step = 1; 
		this.nth = -1;
		this.force_stop = false;
		this.first = true;
		
		this.step1 = {};
		this.step3 = {};
		this.step3.tradeinfo = {};
	/*
		// test interface
			var start_opt ; var start_nth =0; var len =0;
			if ( $('#h_level').val() ) {
				start_opt = $('#h_level').val().split(",");
				debug.log ( this, ' Got opt : ' , start_opt);
				start_nth = parseInt( start_opt[0] );
				len = start_opt[1] ? parseInt( start_opt[1] ) : 0;	// not set .. to the end.. 
			}
			
			debug.log ( this, ' h level', start_nth , 'len', len);
	
			var seq_len = 		this.taskSeq.length ;
			
			if ( len > 0  && start_nth + len < seq_len ) {
				// cut : splice :: This method changes the original array!
				this.taskSeq.splice( start_nth + len , seq_len - start_nth - len ); // start , n 
				debug.log(this, ' ori seq_len: ', seq_len,  ' \t Spliced Seq : len : ', this.taskSeq.length );
	
			}
			
			if ( start_nth ) {
				// do only 1 action 
				this.nth = start_nth -1; // start with ++1
								   // var end  = ( start_nth + len >  seq_len ) ? seq_len : start_nth + len;
				// this.taskSeq = this.taskSeq.slice( start_nth , end ); // setart, end 
				// debug.log(this, ' ori seq_len: ', seq_len,  ' \t slice ed  : len : ', this.taskSeq.length );
				
				this.test_one_action = true;
				this.start_nth = start_nth;
				return;
			} 
			
			// g > 20 0000  start at step 3 
			var res  = em.cstlmgr.getCurCstl().res;
			if ( res.g > 80000 ) {
				this.step = 3;
				return;
			}
					
			
			// get prev state 
			this.getStoredState();*/
	
	},
	
	reinit: function() {
			this.nth = -1;
	},
	
	stop: function() {
			this.force_stop  = true;
	},
	resume: function() {
			this.force_stop  = false;
	},
	
	// when restart : get prev  proceeding state 
	getStoredState: function() {
		// get stored state 
		var stored_state = CUtil.getStorage('InitQ_' +  CDB.getCurUserName());
		if ( stored_state ) {
			this.step = stored_state.step;
			this.subs = stored_state.subs;
			this.nth = stored_state.nth;
			debug.log( this, ' Get prev stored stgate: ',stored_state , this.step, this.subs,  this.nth );
		}
		else {
			debug.log( this, 'No stored Info : STart New ');
		}
	},

	stampState: function( ) {
		debug.log(this,  'stampState !!! ');
		CUtil.saveStorage('InitQ_' +  CDB.getCurUserName() , { step: this.step , subs: this.subs, nth: this.nth } );		
	 },	
	
	
	// entry from sp mgr : with u_s, dfd 
	startSPAction: function (   dfd ) {
		this.dfd = dfd;
		
		var self  = this;
			// if no info
		if ( this.first ) {
			this.first = false;
			
			 // bless >= 2  && qid 18 is done  :: step 3 
			 // id 18 : hire hero :: must be done  :: when done  id 18 is disappaered.. !!.. how to check ??  
			 // var userinfo = CDB.getCurUserInfo();
			 var cstlinfo = em.cstlmgr.getCurCstl();
			 var min_sty_lv = cstlinfo.getStudyLv ( CDB.STUDY.MARCHING ) | cstlinfo.getStudyLv ( CDB.STUDY.SCOUTING ); 
			  
			 debug.log( this, ' Check ================= step : ', min_sty_lv  , CDB.STUDY.MARCHING , CDB.STUDY.SCOUTING);
			 // if  ( em.cstlmgr.getBlessCnt() >= 2  && min_sty_lv  >= 1  ) {  //&&  em.accmgr.getQusetState(18).done ) {
			 if  ( min_sty_lv  >= 1  ) {  //&&  em.accmgr.getQusetState(18).done ) {
			 	this.step = 3;
			 } else {
			 	this.step = 1;
			 }
			 
			 if ( this.step == 1 ) {
				 // when step 1.. get stored state 
			 	 this.getStoredState();

				 // check valid get state 
				 if ( ! this.step  ||  !this.subs ||  ! this.nth  ) {  // no info  // check sub 
				 	// decide sub step .. 
				 	this.step =1;  this.subs = 0; 
				 	
				 	// if uni lv >=  1 subs 1
				 	var uni_lv = cstlinfo.getBldLv ( CDB.BUILD.UNI ) ;
				 	var barr_lv = cstlinfo.getBldLv ( CDB.BUILD.UNI) ; 
				 	
				 	if  ( em.cstlmgr.getBlessCnt() >= 2  
				 			&& uni_lv  ==  1  ) {  
						this.subs = 1;
					} 
					if ( em.cstlmgr.getBlessCnt() >= 2  
				 			&& uni_lv ==  2  ) {  
						this.subs = 2;
					}
					if ( em.cstlmgr.getBlessCnt() >= 2  
				 			&& uni_lv >= 3 ) {  
						this.subs = 3;
					}

				 }
			 }
			this.startStep( this.step, this.subs);
			
		} else {
			
			// start with prev state 
			this.startStep( this.step, this.subs);
		}
		
		
	},
	
	// start !!! with step info 
	startStep: function( step, subs ) {
		this.step = step;
		this.subs = subs;
		
		var self = this;
		// start each step :: 
		function start_step() {
				// after 30 : try donate..!!! 
				// check grade >= 30 :: before start.. 
/*
				var userinfo = CDB.getCurUserInfo();
				if ( userinfo.grade >= 30 ){
					
					self.dfd.resolve();
					return;
				}
*/

				if ( self.step == 1) {
					self.startStep1(subs);
				}	else {
					self.startStep3();
				}
		};
		
		var cstlinfo = em.cstlmgr.getCurCstl();
		em.tasks.getCstlInfos(cstlinfo, start_step) ; 
/*
				
		// move cstl  // cd list update... 
		var cb_cstlmove;
		em.cbs.cstlmove1done.add( cb_cstlmove = function( ){ 
						em.cbs.cstlmove1done.remove( cb_cstlmove);
						debug.log( self, 'Start Step:::', step, subs);
						// go next 
						start_step();
					}  );
		em.cstlmgr.moveCstlAt(0);*/

	},
	
	startStep1: function( subs ) {
		debug.log(this,  'startStep1  start !!!  subs: ', subs);
		this.curSubSeq  = this.taskSeq [subs];
		
			this.step1.cit_timer = setInterval( function() {
					// get cit info : update res 
					em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
							function(data) {
							}); // get cit info  		
				}, 30000) ;
		
		this.nth = -1;	// reset 		
		this.startStep1Subs( subs );
	 },
	 
	startStep1Subs: function( subs ) {
		debug.log(this,  'startStep1  start !!!  subs: ', subs);
		
		// check  force stop 
		if ( this.force_stop ) {
				this.dfd.resolve();
				return;
		} 
				
	// get next from cur Sub Seq 		
		var task = this.getNextTask();
		this.doTask(task);
	 },
		
/*
	Step1Finished: function() {
		debug.log (this, 'Step1Finished finishied!!!');
		
		// wait until all tk is sold 
		this.step = 2;
		
		this.startStep2();
	},*/


	getNextTask: function () {

		 // check complete 
		if ( ++this.nth >= this.curSubSeq.length) {
			return undefined;		
		}
		debug.log( this, ' cur task : ',  this.nth, this.curSubSeq[this.nth]) ;
		return this.curSubSeq[this.nth];	
	},
	

	doTask: function( task ) {
		
			// end subs 
		if ( task == undefined ) {
			// finish... set stamp ... 
			clearInterval( this.step1.cit_timer );
			em.infoview.showCurIng(this.step,  'Step:' + this.step + ' Sub:' + this.subs + ' Done!');

			this.subs ++; this.nth = -1;
			
			 // done all step  1 sub seq.. go to step 3 
		 	 if( this.subs >= this.taskSeq.length ) {
		 	 	this.step = 3;
		 	 }
		 	 
			this.stampState();
			
			//  go next user action 
			this.dfd.resolve();
			return;
		} 
		
		if ( task && task.fn ) {
			debug.log(this, '\n\n ============= Cur Do task:', task.name, task.retry, task.param);
			
			// em.util.print_result( 'INITQ: ' + task.name + ' : Start == s:n ' + this.step + ':' + this.nth);
			em.infoview.showCurIng(this.step, task);
			
			// task.fn.apply(this, [ task, task.param , this.doNext]);
			this[task.fn].apply(this, [ task, task.param , this.doNext]);
		} else {
			debug.log ( this, 'ERROR INVLAID TASK !!!');
					//  go next user action 
			this.dfd.resolve();
		}
	},
	
	// recv result from prev task 
	// check  task entity 
	// sucess / fail check 
	//  retry? or skip 
	// wait complete ? -> set interval .  check cd list 
	//    when  cd is end - > re enter this. 
	// do next 
	doNext : function(task, result) {
		var self = this; 
		
		if (!task) {
			debug.log( this, 'No Task... specified.. : return');
			return;
		}
		
		// check  task entity
			// noti ui cur state 
		debug.log(this, ' 	Done task:', task.name, task.retry);
		debug.log(this, ' 	task Result :', result.succ ,  result);
		debug.log(this, ' 				Done task: \n', task.name, task.retry);
		// debug.log(this, ' Done task: \n\n\n ', task.name, task.retry);
		debug.log(this,  'INITQ: ' + task.name + ' : ' + (result.succ == true ? 'Succ' : 'Fail') );
		
		// noty view 
		em.infoview.showCurIng(this.step, task, result);
		
		if ( result.succ ) {
			// stamp state 
			this.stampState( task);
				// just do next
				var task = this.getNextTask(); 
				setTimeout( function() { self.doTask( task ); }, CUtil.RandTime(500) ); 
		 
		} else {
			// critical falit : 
			// 		stop seq.  set stamp ;  to restart next enter. 
			if ( task.fault_action == 'abort' ) {
				// alert( '############################  Task is Failed.. Critical !' + task.name);
				em.infoview.showCurIng(this.step, task.name + 'ERR:Abort!');
				this.dfd.resolve();
				return;
			} 
			
			//  when fail.. go next !! or stop !!.  
			else {
				debug.log(this, '\n \t ************ Error in action ', task , ' just go next act '); 
				// just do next
				// self.doTask( this.getNextTask() );
				setTimeout( function() { self.doTask( self.getNextTask() ); }, 1000 );
			}
		}
	},
	

	
	
	
	/*
		 step 2  
	*/
	
	// wait until ally tk is soled 
	startStep2: function() {
		var self = this;
		clearInterval( this.step1.cit_timer );
		// set timer for cit info 
		this.cit_timer = setInterval( function() {
					// get cit info : update res 
					em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
							function(data) {
						
								debug.log( self, ' STEP 2: Wait trade sold!! ', data);
								self.checkAllyTkSold( 2, 
									function () {	// done : soled 
										
										// clear  & go step 3 
										clearInterval( self.cit_timer );
										self.step = 3;
										setTimeout( function() { self.startStep3(); } , 0 );
									}
								);
							}); // get cit info  		
				}, this.cit_timeout) ;
		
	

		 
	},
	
	checkAllyTkSold: function  ( step,  cb ) {
		var res  = em.cstlmgr.getCurCstl().res;
		debug.log( this, ' checkAllyTkSold,  IN  step :', step, ' new G: ',  res.g);
		
		// first check : just store.. res 
		if ( ! this.prev_res ) {
			// deep copy 
			this.prev_res = {};
			$.extend( this.prev_res , res);
			return;
		}
		
		debug.log( this, ' checkAllyTkSold,  this.prev_res.g :', this.prev_res.g, ' new G: ',  res.g);
		if( step >= 2 &&  res.g > this.prev_res.g + 100000) {
				debug.log( this, ' Gotcha . TK is sold ,  IN  step :', step, ' new G: ',  res.g);
				cb ( ) ;
		}
		// this.prev_res = res;
		// deep copy 
		$.extend( this.prev_res , res);
	},
	
	/*
		 step 3  -------------------------
	*/
	
	__STEP3___BEGIN______: function() {},
	
	
	startStep3: function() {
		var self = this;
		// force stop 
		if ( this.force_stop ) {
			self.dfd.resolve();
			return;
			} 
		// this.step3.cit_cnt = 0;
		
		// set step 3 
		this.stampState();
		 
		// check cit info : to update lv 
		// & check to sold trade  item . 
		this.step3.cit_timer = setInterval( function() {
			em.tasks.getCitInfo( em.cstlmgr.curCstlID(), 
					function() {
						//check trade 
						self.checkAllyTkSold( 3, 
							function () {	// done : soled 
								// self.step3.tradeinfo.status = false;
								self.step3.tradeinfo.status = 'Enough';
	  							em.infoview.showTradeStatus (self.step3.tradeinfo);
							}
						);
						
						// check sutdy
						// -- will be done by sp30 panel : updatae priodically 
/*
						if ( self.step3.cit_cnt++ > 3 ) {
							self.step3.cit_cnt = 0;
							
						}
*/
				}); 		
			}, this.cit_timeout) ;
			 
		this.step3Monitor();
	},
	
	step3Monitor: function() {
		var outer = this;
		var self = this;
		var cstlinfo = em.cstlmgr.getCurCstl();
		
		debug.log ( this, ' step3Monitor ::', this.step3 );
		
		// force stop 
		// if ( this.force_stop ) return; 


		var actions = {
			name: 'step3',
			context: this, 
			action_table: [


			// check Gl 
				{ 
					cmd: 'check G',
					doParam: {  },
					cb : function(data) {
							debug.log ( self, 'check G ::', data ); 	
							if ( typeof data === 'object' &&  data.code == 0 ) {
								debug.log ( self, 'check G :: Success ~~~~~~~~~~~', data );
							}
							setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.checkG,
				},	
				
			// try bld 
				{ 
					cmd: 'Try_bld',
					doParam: { },  
					cb : function(data) {
									debug.log ( self, ' Try bld ::', data );
									
									// space in bld slot : try more 
									if ( data.code == 0  && data.slot < 3 ) {
										outer.actionSeq.retryCurAction('Try_bld');
									} 	
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
					},
					doFunc:	 self.tryBld,
				},	
				// try train  : to use h first 
				{ 
					cmd: 'Try Train',
					doParam: { 'type': 2, 'num': 5000 } , 	// disband all  
					cb : function(data) {
									debug.log ( self, ' Try Train ::', data ); 
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.tryTrain,
				},					
			// try study
				{ 
					cmd: 'Try study',
					doParam: { },
					cb : function(data) {
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
									debug.log ( self, ' Try study ::', data ); 	
						},
					doFunc:	 self.tryStudy,
				},	

				],
				done_cb:function () { 
					// done step3 .. 
					// clear time 
					clearInterval( self.step3.cit_timer );
					
					// noty view 
					em.infoview.showCurIng( self.step, 'Seq Done:T last ' + self.curTrainNum );
						
					//  go next user action 
						self.dfd.resolve();
							// restart this action seq after some time. 
							// setTimeout( function() { self.step3Monitor.call( self ); } , this.cit_timeout + 5000 ); // 1 min later 
					 },			// cb for complete action  	
		};
	
	
	
		var userinfo = CDB.getCurUserInfo();
		if ( userinfo.grade >= 30 ){
			// remove others except  donate & check G 
			 // actions.action_table.splice(1, actions.action_table.length-1);
			// only donate... :: 
			actions.action_table = [] ;
			// actions.action_table.push(
			actions.action_table.unshift(
							// try donate 
				{ 
					cmd: 'Try donate',
					doParam: { },
					cb : function(data) {
									debug.log ( self, ' Try donate ::', data ); 	
									setTimeout( function() { outer.actionSeq.next.call(outer.actionSeq); } ,CUtil.RandTime(2000)); 
						},
					doFunc:	 self.tryDonate,
				}	
				 ); 
		}

	
		this.actionSeq.setAction(actions);
		this.actionSeq.start();
	},
	
	// check possible  
	// disband
	// train 
	tryTrain: function(aparam, cb) {
		var self = this;
		// noty view 
		em.infoview.showCurIng( this.step, 'tryTrain..:last ' + self.curTrainNum );	
		
		var cstlinfo = em.cstlmgr.getCurCstl();
		// var barr_lv = cstl.city[ CDB.BUILD.BAR.pos ];
		var barr_lv = cstlinfo.getBldLv ( CDB.BUILD.BAR) ;
		
		var ef_lv = cstlinfo.getStudyLv ( CDB.STUDY.EFF_TRAINING ) ;

		debug.log( this, ' tryTrain ::', barr_lv, ef_lv, cstlinfo, em.tasks);

		// check possible  : ef > 0 , bar > 2  : 
		// XXX:  not train when ef is  0 !!!!  ineffective 
		// if ( barr_lv < 3 ||  ef_lv < 1) {
		if ( barr_lv < 3 ||   cstlinfo.getStudyLv ( CDB.STUDY.SCOUTING ) < 1 ) {
			debug.log( this, ' Can t  train Sp  low barr, or not study scout..... ', barr_lv );
			cb(-1);
			return;
		}
		
		//	check cd list if training..
		// var cstlinfo = em.cstlmgr.getCurCstl();  
		cstlinfo.clearExpired (CDB.CDS.TRAIN );
		var ings = cstlinfo.findCdTypes (CDB.CDS.TRAIN );
		if ( ings.length >= 1 ) {
			debug.log( this, ' Train is doing...');
			cb(-1);
			return;
		}
		
		// noty view 
		em.infoview.showCurIng( this.step, 'Disbanding...');
			
	  // disband : update cur sol state : check max num
	  var trs  = { s: aparam.num , type: aparam.type, num: aparam.num }; // max 50000  : all spy disband 
	  em.tasks.disbandSols (trs, function(result) {
	  		if ( result && result.code != 0 ) {
	  			debug.log ( self, ' ERROR in disband!!', result);
	  		}
	  		// do train   --  don t care disban result.. 
	  		spTrain();
	  } ); 
	  
		// train  after disband 
		function spTrain() {
			debug.log(self, 'spTrain');
			
			// noty view  : 
			var userinfo = CDB.getCurUserInfo();
			self.curTrainNum = ( ef_lv *  7	 * userinfo.grade  + 90);
			em.infoview.showCurIng( self.step, 'Training...' +  self.curTrainNum );
			
			var trs  = {type : 2 , num : self.curTrainNum };	
			// calc res  : compare to cstl res 
			var res  = em.cstlmgr.getCurCstl().res;
			
			// calulate resorece !!!
			var per_res =  CDB.SOLS.COST[trs.type];
			var cost = {};
			$.each( Object.keys(per_res) , function (i, item) { 
				cost[item] = per_res[item] * trs.num; 
			});
			
			console.log( ' per_res ' , per_res);
			console.log( ' cost ' , cost);
			
			debug.log( this, ' build Need cost: ', cost);
	
			var calc_ret = CUtil.calcNeedRes(res, cost , 100);
			
			em.tasks.trainSol(em.cstlmgr.getCurCstlIdx(), 
						trs,		
						// {g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total } ,
						calc_ret,  
						function (data) {
							cb(data);	 
						} 
				);
		};	
		
	},	
	
	
	// check empty bld slot 
	// get bld table.  
	// check cur bld state 
	// pop done bld action
	// try next bld 
	
	// 1. check slot 
	// 2. cur blding ?  
	// N :  lv :  > curlv  ==> doBld  or skip  
	//  Y :  find next not blding WB ( wanted bld )
	// 		pop wb from tbl :  
	//			wb is blding - > push ings
	//			wb is not blding  -> do Bld  -> return
	//			reorganaze tbl :  ings + remain Tbl 
	tryBld:  function(aparam, cb) {
	  	var cstlinfo = em.cstlmgr.getCurCstl();
	  	
		// noty view 
		em.infoview.showCurIng( this.step, 'tryBld ...'   );	
		  	
		// check empty bld slot
		cstlinfo.clearExpired (CDB.CDS.BLD );
		var bld_cds = cstlinfo.findCdTypes (CDB.CDS.BLD );
		if ( bld_cds.length >= 3 ) {
			debug.log( this, ' All 3 slot is blding...');
			cb(-1);
			return;
		}

		function bNowBlding (type) {
			// check current blding ?  : type, lv  both same. 
			var now_blding = bld_cds.filter ( function(el) { 
				return ( el.target == type )  ; 
				});
			return now_blding.length;
		}
			
		// get bld table.
		// [name, lv, type]  
	  	var cur_blds = cstlinfo.getBlds();
	  	// check cur bld state 
	  	while ( this.step3_bld_tbl.length !=0  ) {

	  		// get first  // [ CDB.BUILD.FAC.type, 1 ],
	  		var wb = this.step3_bld_tbl.shift() ;

			debug.log( this, 'tryBld :: cur : ', cur_blds, ' wb:', wb);
	  		// get  cur lv of wb    : cur_bld [ name, lv, type ]
	  		var cur_wb = CUtil.findElArrByValPos ( cur_blds,  wb [0]  /* bld type */ , 2 /* positoin */ );
	  		// var cur_wblv = (cur_wb !== undefined) ? cur_wb[1] : 0 ;
	  		// bld is always has value ..  in city info array   	
			
			// lv check :  cur lv > want lv : skip   
			if ( cur_wb[1] >= wb[1]  ) { // already done : cur 8,  want  8  : done..
				debug.log( this, 'tryBld :  Already Done: ', wb, cur_wb);
				continue; 
			} 
			
			if ( bNowBlding(wb[0]) ) {
				debug.log( this, ' Now Blding.. :: ', wb,  ' cur cds: ', bld_cds ,'Find Alt WB : ') ;
				
				// find not blding wb 
				var ings = [];
				
				// push back cur wb  !!!  
				ings.push(wb); 
				
				var avail_wb;
				/// pop wbs &   put  ings arr  
				while ( this.step3_bld_tbl.length !=0  ) {
						var alt_wb = this.step3_bld_tbl.shift();
						debug.log( this, ' Alt WB : ' , alt_wb) ;
						
						// get  cur lv of wb    : cur_bld [ name, lv, type ]
				  		var cur_alt_b = CUtil.findElArrByValPos ( cur_blds,  alt_wb [0]  /* bld type */ , 2 /* positoin */ );
						// lv check :  cur lv > want lv : skip   
						if ( cur_alt_b[1] >= alt_wb[1]  ) { 
							debug.log( this, 'tryBld :  Already Done: alt_wb ', alt_wb, ' cur_alt_b:', cur_alt_b);
							continue; 
						} 
						
						if ( bNowBlding(alt_wb[0]) )  {		// is blding ?
							debug.log( this, ' Is blding : push ings' , alt_wb) ; 
							// push ings 
							ings.push(alt_wb);
						}
						else {		// found aval wb : do bld
							debug.log( this, ' Found Alt WB  : Do Bld ' , alt_wb) ;  
							avail_wb = alt_wb;
							break;
						}
				}
				
				// re make bTbl 
				this.step3_bld_tbl = ings.concat(this.step3_bld_tbl);
				// do bld  if alter wb is exist 
				if ( avail_wb ) {
	  				this.conductBld ( undefined ,  {bld: avail_wb[0] , lv: avail_wb[1] -1 } , // reqres start index with 0 : need -1   
	  						function(task, result) { 
	  							if ( result.succ ) {
		  							result.slot = bld_cds.length +1 ;
	  							} else {
	  								result.slot = 3; // end :  try bld. 
	  							}
	  							cb(result); } );	
	  				
	  				return;	// cb is called.. return 
				}

				// exit while loop when no op 
  				break;
				
			} else {

				debug.log( this, 'tryBld :  do Build ~~~~~~~~~~~~~~~~~ : ', wb, cur_wb);
				
				// do bld 
  				this.conductBld ( undefined ,  {bld: wb[0] , lv: wb[1] -1 } , // reqres start index with 0 : need -1   
  						function(task, result) {
	  							if ( result.succ ) {
		  							result.slot = bld_cds.length +1 ;
	  							} else {
	  								result.slot = 3; // end :  try bld. 
	  							}
 
  							cb(result); } );	
  				
				return;		
			}
			
	  	} // while 
	  	
	  	cb(-1);
	},
	
	// check empty bld slot 
	// get bld table.  
	// check cur bld state 
	// pop done bld action
	// try next bld 
	tryStudy:  function(aparam, cb) {
	  	var cstlinfo = em.cstlmgr.getCurCstl();
	  	
		// noty view 
		em.infoview.showCurIng( this.step, 'tryStudy ...'   );	
		
		// check empty study  slot
		cstlinfo.clearExpired (CDB.CDS.STUDY );
		var ings = cstlinfo.findCdTypes (CDB.CDS.STUDY );
		if ( ings.length >= 1 ) {
			debug.log( this, ' All study slot is doing...');
			cb(-1);
			return;
		}

		// get studies 
	  	var cur_state = cstlinfo.studies;
	  	// check cur sty state 
	  	var o_tbl = this.step3_study_tbl;
	  	while ( o_tbl.length !=0  ) {

	  		// get first 
	  		var act = o_tbl.shift() ;
	  		debug.log( this, 'tryStudy :: act: ', act);

	  		// find  entity type  in  cur tbl  [ type, lv, possible]
	  		// got :  [[1,1,1],[2,1,1],[3,0,1]],"ext":[4,4]}; 
	  		var entity = CUtil.findElArrByValPos ( cur_state,  act [0]  /* entity type */ , 0 /* positoin */ );	
	  		debug.log( this, 'tryStudy :: cur_sty : ', entity);
			 
			// if no entity :  <- unable to study due to uni lv 
			if ( entity === undefined ) {
				debug.log( this, 'Unable Study due to Uni Lv ', act);
				o_tbl.unshift( act ) ; // back 
				
				// check low sty is done ??
				if ( act[0] >= 2 ) {
					act[0] = act[0] -1;		// type : seq..
					act[1] = 1;				// lv
					var below_act = CUtil.findElArrByValPos ( cur_state,  act [0]  /* entity type */ , 0 /* positoin */ );
					//below sty is also not done : try below sty 
					if ( ! below_act ) {
						o_tbl.unshift( act ) ; //  try low  sty  
						continue;
					}
				} 
				// eixt loop : will call cb(-1); : try when next seq. 
				break;
			}
			 
	  		// check already done or need 
	  		if (  entity && entity[1] /* cur lv */  >= act[1] /* want lv */)	{ // lv [1] 
	  			// already done : skip  & remove this.  
	  			continue;
	  		} else {
				// noty view 
				em.infoview.showCurIng( this.step, 'Stying ...' + act[0] + ', l:' + act[1]  );	  	
						
	  			// need to entity : do  :  when  not exist this study or less   
	  			this.conductStudy ( undefined ,  {tech: act[0] , lv: act[1] -1 } , //   cur lv : want lv - 1 
	  						function(task, result) {
	  							// fail : retry :::   
	  							if ( ! result.succ ) {
	  								o_tbl.unshift( act ) ; // back 
	  								debug.log( self, ' Study Fail::: retry !!')
	  							} 
	  							cb(result); } );	
	  			
	  			// already cb called 
	  			return;
	  		} 
	  	} // while
	  	
	  	cb(-1);
	},
	
	
	// check cur res.g 
	// if g < 200000 :  buy ally tk  & reg trade 
/*
	*******************
* Check G :
*  
*   - find tradelit,  will, trade list : 
*      ==  exist : w no check G
* 
*  - if can find mytem in tradelist 
*  		:skip buy 
* 
*   - if find my tem in  will /trade list
*   	: skip trade  
* 
*/	
	checkG:  function(aparam, cb) {
		var self = this;
			// noty view 
		em.infoview.showCurIng( this.step, 'checkG ...'   );	
		
		if ( this.step != 3 ) {
			debug.log(this, ' INvalid step .. .not here CheckG');
			cb(-1);
			return;
		}
		
		var cstlinfo = em.cstlmgr.getCurCstl();
	 	var g = cstlinfo.res.g;		

	  	// check when no trade info  ::  only  first enter 
	  	if (  ! self.step3.tradeinfo.status   ) {
				CheckTradeTem();
	  	} 
		//  check G : less ->  check 
		else if ( g < 400000 ) {
	  		CheckTradeTem();
	  	}  
	  // update view with cur info  
	  //  -- no need to update view...  : no change... 1!! 
	  else  {
	  		// Enough  exit.. 
	  		self.step3.tradeinfo.status = 'Enough';
			em.infoview.showTradeStatus ( self.step3.tradeinfo );
			cb(-1);
/*
		  this.tradeinfo.id =  self.tem_id;	  // <- set with.. tem id 
		  	// status : icon type ,  result : wattime.   id: 
			em.infoview.showTradeStatus (this.tradeinfo);*/

	  }


	


	
	
		// 1 st  fn for checking. 
			// Get info from trade list 
			// data.ctx_xxx <- list
			// check g eoung  .>> return after set info & update view 
		function CheckTradeTem () {
			
			// noty view 
			em.infoview.showCurIng( self.step, 'Check Trade...');
			
			// clear prev trade info
			self.step3.tradeinfo = {};
			
				em.tasks.checkTrade ( self.tem_id , // when buy : id is sid 
		  			function (check_data) {
	  					debug.log( self, ' Result checkTrade  in Step3: ', check_data);
	  					
		  				if( check_data.code != 0 ) { 
		  					debug.log( self, ' ~################ ERROR in checkTrade  Ally TK in step 3 ') ;
		  					cb(-1);
		  					/// stop 
		  					return;
		  				}
		  				
		  				// update view : trade info with  ,  wait , up  
		  				if (  check_data.willlist.found || check_data.mytradelist.found){
		  					self.notifyTradeInfo(check_data);
	/*
								  if ( check_data.willlist.found ) {
											self.tradeinfo.status = 'Wait Trade';
											self.tradeinfo.remainsec =  check_data.willlist.remainsec ;
											self.tradeinfo.price  =  check_data.willlist.price ;
									  } 
									  if ( check_data.mytradelist.found  ) {
											self.tradeinfo.status = 'TradingUP';
											self.tradeinfo.remainsec =  0;
											self.tradeinfo.price =  check_data.mytradelist.price;
									  }
								  self.tradeinfo.id =  self.tem_id;	  // <- set with.. tem id 
									  // status : icon type ,  result : wattime.   id: 
									em.infoview.showTradeStatus (tradeinfo);*/
	
								cb(check_data);
								// stop  
								return;
		  				}
							
						// if less g : then try  trade 
						if ( g < 600000 ) {
				  				if ( ! check_data.mylist.found ) {
				  						// try buy
				  							// noty view 
											em.infoview.showCurIng( self.step, 'Buy Tem ...'   + self.tem_id);	
											
									  		em.tasks.buyItem ( self.tem_type , self.tem_id , // when buy : id is sid 
									  			function (data) {
									  					debug.log( self, ' Result Buy Tem in Step3: ', data);
										  				if( data.code != 0 ) { 
										  					debug.log( self, 'ERROR in buy  Ally TK in step 3 : no Money??? ') ;
										  					cb(-1);
										  					/// stop 
										  					return;
										  				}
										  				
									  				// try trade 
													checkG_tryTrade (check_data);
									  			}); 
				  				} else {
					  				// try trade 
									checkG_tryTrade (check_data);
				  				}
						} 
						// first enter : check ok & m enough.
						else {
									self.step3.tradeinfo.status = 'Enough';
									self.notifyTradeInfo(check_data);
									cb(check_data);
						}
		  			} // check trade cb 
		  	);
		};
	 
	 		function checkG_tryTrade( check_data ) {
				
				// *   - if find my tem in  will /trade list
				// *   	: skip trade
  				if ( ! check_data.willlist.found &&  ! check_data.mytradelist.found )
  				{
		  			// adjust price : res.g is up-to-date ??? 
		  			// when enter startStep : always update cit info !!!  
		  			var price = self.tem_step3_price;
		  			
		  			if ( cstlinfo.res.g < self.tem_step3_price / 10 ) {
			  			var avail_g = (cstlinfo.res.g > 30000) ? (cstlinfo.res.g - 10000) : cstlinfo.res.g ;

		  				price =  Math.floor ( avail_g *10 / 10000) * 10000  + 1177; // xx0089
		  				debug.log( self, ' Less Money::: Adjust new price!! : ' , self.tem_step3_price);
		  			}
		  			
		  			// do trade  ------
					// noty view 
					em.infoview.showCurIng( self.step, 'Reg Trade ...'   + price);	
	  				 em.tasks.tradeReg (  self.tem_id, 0,  1, price, 
		  					function(data) {
			  						if( data.code != 0 ) { debug.log( self, 'ERROR in Trade Reg Ally TK in step 3 ') ;}
			  						else {
				  						self.step3.tradeinfo.status = 'TradingUP';
			  							debug.log( self, ' SUccess Trade Up!!! ', self.tem_id , price );
			  							debug.log( self, ' Cur Time :  ', CUtil.TimeToString(new Date() ) );
			  							self.notifyTradeInfo( data );
			  						}
			  						cb(data);
		  					} ); 
  				} 
			};  // end fn 

	},
	
	 notifyTradeInfo : function( data ) {
	 	var self = this;
			if (  data.willlist && data.willlist.found ) {
				  self.step3.tradeinfo.status = 'Wait Trade';
				  self.step3.tradeinfo.remainsec =  data.willlist.remainsec ;
				  self.step3.tradeinfo.price  =  data.willlist.price ;
			} 
			if ( data.mytradelist && data.mytradelist.found  ) {
				  self.step3.tradeinfo.status = 'TradingUP';
				  self.step3.tradeinfo.remainsec =  0;
				  self.step3.tradeinfo.price =  data.mytradelist.price;
			}
			if ( data.mylist && data.mylist.found  ) {
				  self.step3.tradeinfo.temcnt  =  data.mylist.temcnt;
			}
		 	self.step3.tradeinfo.id =  self.tem_id;	  // <- set with.. tem id 
		  	// status : icon type ,  result : wattime.   id: 
			em.infoview.showTradeStatus ( self.step3.tradeinfo );
	},
	
	tryDonate:  function(aparam, cb) {
		var self = this;
		
		var u_info = CDB.getCurUserInfo();
		

/*
		// tremp :: 
				em.tasks.quitAlly( u_info.userid,  function(data) {
					if ( data.code == 0 ) {
						debug.log( self, 'Quit  Ally OK !!! \n\n\n');
						// noti view 
						em.infoview.informAllyState ('Quit Done');
					}
					cb(0);
				});*/


		
/*
		// temp.!!! 紐낆삁..  50 留�湲곕�.. 
		var cstlinfo = em.cstlmgr.getCurCstl();
	 	if ( cstlinfo.res.g <= 500000)  {
	 			em.infoview.informAllyState ('not enough G !!' );
				cb(0);
				return;
	 	}*/

	 	
		// check subscribed state
		if ( ! u_info.guild  && ! self.applyAlly ) {
				// try apply 
				em.tasks.applyAlly( function(data) {
					if ( data.code == 0 ) {
						debug.log( self, 'Apply Ally OK !!! \n\n\n');
						// noti view 
						em.infoview.informAllyState ('Apply Done');
					}
					cb(0);
				});
				self.applyAlly = true;
				return;
		}
		
		// not member of ally.  exit 
		if ( ! u_info.guild   ) {
				cb(0);
				return;
		}
		
		debug.log( self, ' Gld : ', u_info.guild );
		
		var cstlinfo = em.cstlmgr.getCurCstl();
	 	var donate_g = cstlinfo.res.g;	

/*
	 	if ( donate_g <= 500000)  {
	 			em.infoview.informAllyState ('not enough G !!' );
				cb(0);
				return;
	 	}*/

	 	// var tech_o_ar = [ [1,30000] , [5,75000], [4,75000] , [11,200000], [10,200000] ];
	 	var tech_o_ar = [[16,500000], [5,75000], [12,200000], [11,200000] ];
	 	
		// check subscribed status & get cool time
		// try donate with all remain g   
		em.tasks.donate( donate_g,  tech_o_ar, function(data) {
			// if cool remains return. 
			debug.log(self, 'tryDonate done:  ' ,  data);
			
			if ( data.code == -1 ) {
				debug.log( self, ' Not Yet joined.... \n\n');
				cb(0);
				return;
			}
			
			// remains cool 
			if ( data.code == 1 ) {
				// noty view : cool 
				debug.log ( self, 'Cool time : ', data.hall_cool );
				
				em.infoview.informAllyState ('Cool', data.hall_cool);
				cb(0);
				return;
			}
			
			if ( data.code == 100) {
				// only hall is avlable	
				debug.log ( self, 'Only Hall Done !! : ', data.hall_domax );
			}


		em.infoview.informAllyState ('Donate Done' + data.hall_domax );
		debug.log(self, 'Done!!! donate ');
		
		// if option is set to quit after donate : quit ally 
		if (  u_info.quit_after_donate )  {
				em.tasks.quitAlly( u_info.userid,  function(data) {
					if ( data.code == 0 ) {
						debug.log( self, 'Quit  Ally OK !!! \n\n\n');
						// noti view 
						em.infoview.informAllyState ('Quit Done');
					}
					cb(0);
				});
		} else {
			cb(0);
		}
		}) ;
		
	},
	
	// ================================================ 
	// each  task    
	
	
	___EACH_FUNCTION_DEFINE______: function() {} ,
	// 1 shot task :  use ahelper  : direct cb 
	getGift: function( task,  code, cb ) {
		
		var self = this;
		debug.log(this, 'this', this, task);
		// use action helper
	 	var username = CDB.getCurUser();
		var param = { 'user': username, 'code': code,  
				cb : function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					} 
				};
		em.ahelper.gift(param);		
	},
		/*
			GET /game/get_userinfo_api.php?jsonpcallback=jsonp1326014287292&_=1326016300674&key=0314fac3e037989c062370584d3dc99b&_l=en&_p=EW-DROID HTTP/1.1

		*/
	getUserInfo:  function( task,  param ,cb ) {
		
		var self = this;
		debug.log(this, 'this', this, task);
		// use action helper
		var param = { 
				cb : function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					} 
				};
		em.ahelper.get_userinfo_api(param);		
	},
	trainSol:  function( task,  param , cb) {
		
		var self = this;
		debug.log(this, 'this', this, task);
// 'sol_type': 1, 'sol_num': 10

		// calc res  : compare to cstl res 
		var trs = param.trs;
		// calulate resorece !!!
		var per_res =  CDB.SOLS.COST[trs.type];
		var cost = {};
		$.each( Object.keys(per_res) , function (i, item) { 
			cost[item] = per_res[item] * trs.num; 
		});
		
		var calc_ret = CUtil.calcNeedRes(em.cstlmgr.getCurCstl().res, cost , 100);

		em.tasks.trainSol(em.cstlmgr.getCurCstlIdx(), 
					trs,
					calc_ret ,  // exchange res 
					function (data) {
						// succ/ fail check
						if ( data.code == 0 ) {
							data.succ = true;
							// move cstl to update new res 
							var cb_cstlmove ;
							em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
							em.cbs.cstlmove1done.remove( cb_cstlmove);
							if( cb) {	cb.apply (self, [ task, data ]);	}	 
							}  ); 
							
							em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );
						} else {
							data.succ = false;	
							debug.log( self, ' TRain Fail... ', data);
							if( cb) {	cb.apply (self, [ task, data ]);	}	  
						}
					} 
					);
	},
	
	buyGemItem:  function( task,  param , cb) {
		var self = this;
		debug.log(this, 'this', this, task);

		em.tasks.buyGemItem(	 param.cat , param.id ,
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	 	 
					} 
					);
	},
	
	hireH:  function( task,  param , cb) {
		
		var self = this;
		debug.log(this, 'this', this, task);

		em.tasks.hireH( 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	 	 
					} 
					);
	},
	
							
	// use dfd . tasks : when  		
	// if task == undefined.  do not go next 
	conductBld	: function( task,  param , cb ) {
		var self = this;
		
		var type;
		if ( typeof param.bld === 'number') {
			 type= param.bld;
		} else {
			 type= param.bld.type;
		}
		var lv = param.lv ;
		
		var cstlinfo = em.cstlmgr.getCurCstl();
		var cur_lv  = cstlinfo.getBldLv ( param.bld  ) ;

		debug.log( this, ' param: type ', type, 'lv:', lv , ' CurLv', cur_lv);
		// !! caution :  param.lv is not want lv. : cur lv..
		if ( cur_lv >  param.lv ) {
			// already done .. skip
			if( cb) {	cb.apply (self, [ task,  {succ: false } ] );	}	 			
			return;
		}
				
		var dfd = $.Deferred();

		// noty view 
		em.infoview.showCurIng( this.step, 'Blding ...' + type + ', l:' + param.lv );
		// only success
		$.when(dfd).then( function(result) {
			//	{"code":0,"ret":{
// 			// "cdlist":[{"id":847443,"cdtype":1,"target":"8","owner":0,"secs":521}]}})
						debug.log(self, 'ret BUILD Success!!', result);
						if ( result.code == 0 ) result.succ = true;
						
						// move cstl to update new res 
						var cb_cstlmove ;
						em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
						em.cbs.cstlmove1done.remove( cb_cstlmove);
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
						}  ); 
						
						em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );
						
						// if( cb) {	cb.apply (self, [ task, result ]);	}	 
					}
					, function(result) {
						var error_str = '';
						if( result.code == 704 ) error_str = 'no slot for bld: need bless of bld'; 
						if( result.code == 708 ) error_str = 'Need more Res.. check !!'; 
						//alert('build fail :' + result.code + error_str);
						result.succ = false;
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
					}
		);


		
		// calc res  : compare to cstl res 
		var res  = em.cstlmgr.getCurCstl().res;
		// remain minimum f : 
		var cost = CDB.getBuildRes(type, lv) ;	
		//cost.f += CDB.getCurUserInfo().MinFood;
		debug.log( this, ' build Need cost: ', cost);


		var calc_ret = {} ;
		if ( ! cost ) {	// no info build cost : not important.. just build 
			calc_ret =  {'possible': true, 'exchange': {f:0, w:0, i:0 , total: 0 } };			
		}  else {
			calc_ret = CUtil.calcNeedRes(res, cost , 0);
		}

		em.tasks.doBuild( dfd, type, {g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total }  );
		
	},		
		
	// use dfd . tasks : when  		
	conductStudy	: function( task,  param , cb ) {
		var self = this;
	
		debug.log(this, 'conductStudy ', param);
		
		// calc res  : compare to cstl res 
		var res  = em.cstlmgr.getCurCstl().res;
		var cost = CDB.getStudyRes( param.tech, param.lv) ;	
		debug.log( this, ' getStudyRes Need cost: ',  cost , 'cur res: ', res);
		var calc_ret = CUtil.calcNeedRes(res, cost , 100 );

		// check possible 
		if ( ! calc_ret.possible  ) {
				// update status ... 
			debug.log(this, 'Not Enough Res!!  IN conductStudy  ' );
			if( cb) {	cb.apply (self, [ task, {succ:false} ]);	}
			return;
		}
		
		var dfd = $.Deferred();

		// OK : COLOR -> YELLOW
		// result - > cd list  update to cstlmgr by tasks 
		function processRet(result) {
				debug.log( self, 'conductStudy : result ', result);
				if (result.code == 0 && result.ret && result.ret.cdlist ) {
					result.succ = true;
					debug.log(self, 'ret Sutdy Success!!', result);
				
					// move cstl to update new res
					var cb_cstlmove ;
					em.cbs.cstlmove1done.add( cb_cstlmove = function () { 
						em.cbs.cstlmove1done.remove( cb_cstlmove);
						if( cb) {	cb.apply (self, [ task, result ]);	}	 
						}  ); 

					em.cstlmgr.moveCstlAt( em.cstlmgr.getCurCstlIdx() );

				} else {
					result.succ = false;
					debug.log( self, 'conductStudy : FAIL ', result );
					if( cb) {	cb.apply (self, [ task, result ]);	}	 
				}


		};	
		
		// only success
		$.when(dfd).then( processRet, processRet );


		em.tasks.doStudy( dfd, param.tech, 
				{g2f: calc_ret.exchange.f,  g2w: calc_ret.exchange.w, g2i: calc_ret.exchange.i, total:calc_ret.exchange.total }  );
							
	},			
				
	fastActionTem : function( task,  param , cb ) {
		var self = this;
		var type  = param.type ;	
	
		debug.log(this, 'fastActionTem  ::: ', type , param );
		// type, fastid, cdtype, target  , done_cb 
		em.tasks.fastActionTem ( type , param.sid, param.cdtype, param.target,  
					function (data) {
						// succ/ fail check 
						if ( data.code == 0 )			data.succ = true;
						
						debug.log( self, ' FAST ================ \n\n RET \t\t ', data , 'cdid ', data.cdid );
						// update cd list when secs : 0 
						// "code":0,"ret":{"secs":0}}
						if ( data.cdid ) {
							var ret_cd = [ {"id": data.cdid,"cdtype": type,"target":param.target,"owner":0,"secs": data.secs}];
							debug.log( self, ' FAST ================ \n\n UPDATE CDLIST \t\t ', ret_cd, 'cdid ', ret_cd.cdid);
							
							em.cstlmgr.updateCdlist(ret_cd);			
						}
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
			}		);	
		
	},			
	// 1 shot task :   use ahelper  : direct cb 
	conductQst: function( task,  param , cb) {
		
		var self = this;
		
		function conductTask() {
			// use action helper
			var conduct_param = {   'action': param.action, 'id': param.id, 
					cb : function (data) {
						//  task_up :  "code":0,"ret":{"status":2}})
						//  task_end : {"code":0,"ret":{"quest":[{"id":48,"grade":0,"status":0,"done":0}]}})
								// {"id":46,"grade":0,"status":1,"done":0},		//  status : accepted ,  not done
	// 							 		{"id":48,"grade":0,"status":0,"done":1},		// status : 0,  done : done ...
							// succ/ fail check 
							if ( data.code == 0 ) data.succ = true;
							if( cb) {	cb.apply (self, [ task, data ]);	}	 
						} 
					};
			em.ahelper.system_task_conduct (conduct_param);
			return;		
		};
		
		// first  get task list 
		var tasklist_param = { action: 'task_list', cb : function (data) {
									debug.log( self, 'SystemTask List : ', data);
									conductTask();
									}	};
		em.ahelper.system_task_api (tasklist_param);
	},
	
	useItem: function( task,  param, cb ) {
		
		var self = this;
		
// 		GET /game/
/*

// use ref gift 

goods_api.php?jsonpcallback=jsonp1326014287249&_=1326014559916&key=0314fac3e037989c062370584d3dc99b
&action=goods_list
&type=3
&page=1
&_l=en&_p=EW-DROID HTTP/1.1


jsonp1326014287249({"code":0,"ret":{"max":1,
"item":[{"item":
{"id":75614,"sid":167,"num":1},"use":1,"sale":0},
{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},
{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},
{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},
{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},
{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},
{"item":{"id":75606,"sid":169,"num":1},"use":1,"sale":0},
{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},
{"item":{"id":75610,"sid":80,"num":1},"use":1,"sale":0}]}})




GET /game/
goods_mod_api.php?jsonpcallback=jsonp1326014287250&_=1326014568812&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75614
&num=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287250({"code":0,"ret":
{"item":[],"gem":0,"buff":
{"id":6381,"itemid":167,"secs":2592000},"wood":0,"food":0,"iron":0,"gold":0}})

list one more : updtae cur page 


GET /game/goods_mod_api.php?jsonpcallback=jsonp1326014287252&_=1326014587093&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75606
&num=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287252({"code":0,"ret":
{"item":[
{"id":0,"sid":153,"num":1},
{"id":0,"sid":115,"num":3},
{"id":0,"sid":118,"num":3},
{"id":0,"sid":161,"num":3}],"gem":0,
"buff":"","wood":0,"food":0,"iron":0,"gold":0}})


list one more : updtae cur page 




////////////// use chest 


/// use item  : item list 
GET /game/
goods_api.php?jsonpcallback=jsonp1326014287328&_=1326017016998&key=0314fac3e037989c062370584d3dc99b
&action=goods_list
&type=3
&page=1
&_l=en&_p=EW-DROID HTTP/1.1

jsonp1326014287328({"code":0,"ret":{"max":2,"item":[{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},{"item":{"id":75618,"sid":115,"num":3},"use":2,"sale":0},{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},{"item":{"id":75619,"sid":118,"num":3},"use":2,"sale":0},{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},{"item":{"id":75620,"sid":161,"num":3},"use":1,"sale":0},{"item":{"id":75644,"sid":131,"num":1},"use":1,"sale":0}]}})

// use chest 
GET /game/
goods_mod_api.php?jsonpcallback=jsonp1326014287329&_=1326017033995&key=0314fac3e037989c062370584d3dc99b
&action=use
&city=17736
&id=75644
&num=1
&_l=en&_p=EW-DROID HTTP/1.1


jsonp1326014287329({"code":0,"ret":
{"item":[],"gem":0,"buff":"","wood":0,"food":0,"iron":0,
"gold":30000}})


// update 
jsonp1326014287328({"code":0,"ret":{"max":2,"item":[
{"item":{"id":75612,"sid":128,"num":1},"use":1,"sale":0},
{"item":{"id":75616,"sid":190,"num":1},"use":1,"sale":50000},
{"item":{"id":75609,"sid":168,"num":1},"use":1,"sale":0},
{"item":{"id":75618,"sid":115,"num":3},"use":2,"sale":0},
{"item":{"id":75615,"sid":188,"num":1},"use":2,"sale":0},
{"item":{"id":75619,"sid":118,"num":3},"use":2,"sale":0},
{"item":{"id":75611,"sid":126,"num":1},"use":1,"sale":0},
{"item":{"id":75613,"sid":161,"num":2},"use":1,"sale":0},
{"item":{"id":75620,"sid":161,"num":3},"use":1,"sale":0},
{"item":{"id":75644,"sid":131,"num":1},"use":1,"sale":0}]}})



*/

		em.tasks.useItem ( param.type, param.sid, param.id,  param.num, 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},
/*
	sell
*/


	saleItem: function( task,  param , cb) {
		
		var self = this;
		
		em.tasks.saleItem( param.type, param.sid, param.id, param.num , 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},
// buy shop  trade   item 
// ignore param. 
buyTradeItem: function( task,  param , cb ) {
		
		var self = this;
		
		em.tasks.buyItem ( this.tem_type , this.tem_id, 
					function (data) {
						// succ/ fail check 
						data.succ = true;
						
						// jsonp1326014287360({"code":0,"ret":{"gold":32708,"itemid":75656}})
						// save all token id  : for registering. 
						self.allyTokenId =  data.ret.itemid; 
						
						debug.log( this, '\t\t BUY TEM  : ID  : ', self.allyTokenId);
						
						if ( data.code != 0 ) data.succ = false;
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},

	// ignore param. 
	tradeReg: function( task,  param ,cb ) {
		
		var self = this;
		
		var trade_id  = self.allyTokenId;
		// debug.log( this, ' \t\t Trade Reg : ', param);
		debug.log( this, ' \t\t Trade Reg :: TEM.ID : ', this.tem_sid);
		
		var price = self.tem_price;
		var cstlinfo = em.cstlmgr.getCurCstl();
		if ( cstlinfo.res.g < price / 10 ) {
			price =  Math.floor ( (cstlinfo.res.g - 1000 ) *10 / 10000) * 10000  + 1177; // xx0089
			debug.log( self, ' Less Money::: Adjust new price!! : ' , price);
		}
		// em.tasks.tradeReg (  param.sid, param.id,  param.num, param.price, 
		em.tasks.tradeReg (  this.tem_sid, trade_id,  1, price, 
					function (data) {
						// succ/ fail check
						
						// when succ 
						// {"code":0,"ret":{"item":[[2756,113,310089,832]],"max":1}}) 
						if ( data.code == 0 ) {
							data.succ = true;
  							// debug.log( self, ' SUccess Trade Up!!! ', param.sid, param.id,  param.num, param.price );
  							debug.log( self, ' SUccess Trade Up!!! ', self.tem_sid, trade_id,  1, self.tem_price );
  							debug.log( self, ' Cur Time :  ', CUtil.TimeToString(new Date() ) );							
						}
						if( cb) {	cb.apply (self, [ task, data ]);	}	  
					}
					);	
		
	},

	// ignore param 
	checkTrade: function( task,  param ,cb ) {
		var self = this;
		debug.log( this, ' \t\t checkTrade Reg :: TEM.ID : ',  this.tem_id );
		
			em.tasks.checkTrade ( this.tem_id , // when check with sid  
		  			function (check_data) {
	  					debug.log( self, ' Result checkTrade  in Step3: ', check_data);
		  				if( check_data.code != 0 ) { 
		  					debug.log( self, 'ERROR in checkTrade  Ally TK in step  ', self.step ) ;
		  					check_data.succ = false;
		  				} else {
		  					self.notifyTradeInfo(check_data);
			  				if (  check_data.willlist.found || check_data.mytradelist.found){
			  					debug.log( self, 'ERROR in checkTrade  Ally TK in step  ', self.step ) ;
			  					// 0em.util.print_result( '\n\n Trade tem is On the List  \n\n\n <br/>' + CUtil.SecToString( check_data.willlist.remainsec) );	 
			  					// em.util.print_result( '<br/> UP Time :  ' + CUtil.TimeToString( new Date( $.now() + check_data.willlist.remainsec * 1000) ) ); 
			  				}
			  				check_data.succ = true;
		  				}
						if( cb) {	cb.apply (self, [ task, check_data ]);	}		  				
		  			}
		  			);
	},
/*
	GET /game/
	goods_mod_api.php?jsonpcallback=jsonp1326014287254&_=1326014610596&key=0314fac3e037989c062370584d3dc99b
	&action=sale
	&city=17736
	&id=75616
	&_l=en&_p=EW-DROID HTTP/1.1

*/
	// 1 shot task :   use ahelper  : direct cb 
	checkCd: function( task,  param , cb ) {
		var self = this;
		
		// timer 
		function  checkCdTimeFn() {
			// get cd type
			// finish check ?   
			// ok - remove cd . 
			// go next : 
				debug.log(self, ' checkCdTimeFn for task completion :');
					// check cdlist
					
					var bCompleted =  em.cstlmgr.bCompleteCdlist(param.cdtype, param.target );
					
					debug.log(this, 'complete ? :', bCompleted);
					if (  bCompleted  ) {
						// clear this timer 
						clearTimeout( self.cd_timer);
						
						// get cd info when complete cd 
						em.tasks.getCDInfo(em.cstlmgr.curCstlID(),
							 function ( data ) {
								// send task to do next
								var data  = { succ: true};
								if( cb) {	cb.apply (self, [ task, data ]);	}	 
						});
						
					} else {
						if ( task.fault_action == 'abort') {
							var data  = { succ: false};
							if( cb) {	cb.apply (self, [ task, data ]);	}
							return;
						}
						// set next timeout 
						self.cd_timer = setTimeout( checkCdTimeFn , 10000);
					} 
			
					 
		};
		// set timer :  first   : to wait ... loop 
		this.cd_timer = setTimeout( checkCdTimeFn , 0);
	},
	
	
	// when enter seq.. res is already.  updated... 
	// do not get cit info again..!!! 
	CheckRes: function( task,  param ,cb ) {
		var self = this;
		var res  = em.cstlmgr.getCurCstl().res;
		debug.log( this, ' \t\t CheckRes res : ',  param.res , 'curRes:', res);
		
		var result = {succ: false};		
		if ( CUtil.compareRes(res, param.res) > 0 ) {
			result.succ = true;
		} 
		
		if( cb) {	cb.apply (self, [ task, result ]);	}
				
	},	
	
	
	// get cstl info..  : all infos will updated in tasks cbs.. 
	getCurCstlInfo: function( task,  param ,cb ) {
		var self = this;
		debug.log( this, ' \t\t ========== getCurCstlInfo : ' );
		
		var cstlinfo = em.cstlmgr.getCurCstl();
		
		// always success..  
		function update_cur_cstl(result) {
			result.succ = true;
			if( cb) {	cb.apply (self, [ task, result ]);	}
		};
		
		em.tasks.getCstlInfos(cstlinfo, update_cur_cstl) ; 
	},	
	
};

		